﻿using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using System.Web.Security;
using Alma.Models;
using AlmaDatabase;
using DotNetOpenAuth.Messaging;
using DotNetOpenAuth.OpenId;
using DotNetOpenAuth.OpenId.Extensions;
using DotNetOpenAuth.OpenId.Extensions.SimpleRegistration;
using DotNetOpenAuth.OpenId.RelyingParty;

namespace Alma.Controllers
{
    public class UserController : Controller
    {
        private static readonly OpenIdRelyingParty m_openId = new OpenIdRelyingParty ();

        private static readonly Dictionary<string, string> m_openidIdentities = new Dictionary<string, string>
                                                                                    {
                                                                                        {
                                                                                            "google",
                                                                                            @"https://www.google.com/accounts/o8/id"
                                                                                            },
                                                                                        {
                                                                                            "yahoo",
                                                                                            @"http://me.yahoo.com "
                                                                                            },
                                                                                        {
                                                                                            "myopenid",
                                                                                            @": http://www.myopenid.com"
                                                                                            }
                                                                                    };
        public ActionResult Logout()
        {
            FormsAuthentication.SignOut ();
            return RedirectToAction ("Index", "Home");
        }

        public ActionResult Connect()
        {
            //Display Login form
            Session["loginBackUrl"] = Request.UrlReferrer.AbsoluteUri;

            return View("Connect");
        }


        public PartialViewResult ChangeOpenIdProvider(string provider)
        {
            return PartialView ("_OpenIdProvider", provider);
            //return Content(provider);
        }

        [ValidateInput(false)]
        public ActionResult Authenticate(string returnUrl)
        {
            var response = m_openId.GetResponse ();
            if (response == null)
            {
                //Identifier submit
                string provider = Request.Form["provider"];
                if (!m_openidIdentities.ContainsKey(provider))
                {
                    ViewBag.Message = "Provider inconnu";
                    return View("Connect");
                }
                string openidIdentifier = m_openidIdentities[provider];
                Identifier id;
                if (Identifier.TryParse (openidIdentifier, out id))
                {
                    try
                    {
                        var request = m_openId.CreateRequest (openidIdentifier);
                        request.AddExtension (new ClaimsRequest
                                                  {
                                                      Nickname = DemandLevel.Require,
                                                      Email = DemandLevel.Require,
                                                      FullName = DemandLevel.Require,
                                                      Country = DemandLevel.Require,
                                                      Language = DemandLevel.Require,
                                                      BirthDate = DemandLevel.Require,
                                                      Gender = DemandLevel.Require,
                                                      TimeZone = DemandLevel.Require,
                                                  });
                        return request.RedirectingResponse.AsActionResult ();
                    }
                    catch (ProtocolException)
                    {
                        ViewBag.Message = "Could not connect to OpenId Provider " + openidIdentifier + ".";
                        return View ("Connect");
                    }
                }
                else
                {
                    //Provider sending response
                    ViewBag.Message = "Invalid identifier";
                    return View("Connect");
                }
            }
            else
            {
                // Stage 3: OpenID Provider sending assertion response
                switch (response.Status)
                {
                    case AuthenticationStatus.Authenticated:
                        var extensions = response.UnifyExtensionsAsSreg(true);
                        //Session["FriendlyIdentifier"] = response.FriendlyIdentifierForDisplay;
                        using (var context = new AlmaDBEntities())
                        {
                            string identifier = response.ClaimedIdentifier.ToString ();
                            var request = from users in context.Users
                                          where users.OpenId != null && users.OpenId == identifier
                                          select users;
                            User user = request.FirstOrDefault ();
                            if (user == null)
                            {
                                user = new User ()
                                           {
                                               Email = extensions.Email,
                                               IsAdmin = 0,
                                               OpenId = identifier
                                           };
                                //context.Users.AddObject (user);
                                //context.SaveChanges ();
                                //Session["UserId"] = user.ID;
                                return RedirectToAction ("Create",
                                                         new RouteValueDictionary (
                                                             new {controller = "User", action = "Create", openId = identifier, email = extensions.Email}));
                                //return this.RedirectToAction ("Create", "User", new { id = new EmptyUser (user)});
                            }
                            Session["UserId"] = user.ID;
                            FormsAuthentication.SetAuthCookie(user.OpenId, false);
                        }
                        return !string.IsNullOrEmpty((string)Session["loginBackUrl"])
                                   ? (ActionResult) Redirect ((string)Session["loginBackUrl"])
                                   : RedirectToAction ("Index", "Home");
                    case AuthenticationStatus.Canceled:
                        ViewBag.Message = "Canceled at provider";
                        return View ("Connect");
                    case AuthenticationStatus.Failed:
                        ViewBag.Message = response.Exception.Message;
                        return View ("Connect");
                }
            }
            return RedirectToAction ("Details");
        }

        //
        // GET: /User/Details/5

        public ActionResult Details()
        {
            //using (var context = new AlmaDBEntities())
            //{
            //    var user = from u in context.Users
            //               where u.ID == id
            //               select u;
            //    return View(user.First());
            //}
            return View ();
        }

        //
        // GET: /User/Create

        public ActionResult Create(string openId, string email)
        {
            var user = new EmptyUser()
            {
                Email = email,
                IsAdmin = 0,
                OpenId = openId
            };
            return View(user);
        }

        //
        // POST: /User/Create

        [HttpPost]
        public ActionResult Create(User newUser)
        {
            try
            {
                // TODO: Add insert logic here
                if (!ModelState.IsValid)
                {
                    return View (new EmptyUser(newUser));
                }
                using (var context = new AlmaDBEntities())
                {
                    context.Users.AddObject (newUser);
                    context.SaveChanges ();
                    Session["UserId"] = newUser.ID;
                    FormsAuthentication.SetAuthCookie(newUser.OpenId, false);
                }
                return RedirectToAction("Index", "Home");
            }
            catch
            {
                return View();
            }
        }
        
        //
        // GET: /User/Edit/5
 
        [Authorize]
        public ActionResult Edit(int id)
        {
            using (var context = new AlmaDBEntities())
            {
                var user = from users in context.Users
                           where users.ID == id
                           select users;
                return View(new EmptyUser(user.FirstOrDefault()));                
            }
        }

        //
        // POST: /User/Edit/5

        [HttpPost]
        public ActionResult Edit(int id, EmptyUser user)
        {
            if (!ModelState.IsValid)
            {
                return View (user);
            }
            using (var context = new AlmaDBEntities ())
            {
                var users = from u in context.Users
                            where u.ID == id
                            select u;
                var editUser = users.First ();
                editUser.Address = user.Address;
                editUser.Country = user.Country;
                editUser.Email = user.Email;
                editUser.Firstname = user.Firstname;
                editUser.Name = user.Name;
                editUser.Zipcode = user.Zipcode;
                editUser.Town = user.Town;
                editUser.IsAdmin = user.IsAdmin;
                context.SaveChanges ();
            }
            return RedirectToAction("Edit", new { id = id });
        }

        //
        // GET: /User/Delete/5
 
        public ActionResult Delete(int id)
        {
            using (var context = new AlmaDBEntities())
            {
                var user = from users in context.Users
                           where users.ID == id
                           select users;
                return View((user.First()));
            };
        }

        //
        // POST: /User/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, User delUser)
        {
            if (ModelState.IsValid)
            {
                using (var context = new AlmaDBEntities())
                {
                    /*
                    var user = from users in context.Users
                               where users.ID == id
                               select users;
                    context.Users.DeleteObject(user.First());
                     */

                    context.DeleteUser(id);

                }
                return RedirectToAction("Index");
            }
            return View(delUser);
        }
    }
}
